package com.ys.web.mobao.job;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.ys.utils.alipay.AliPayHandler;
import com.ys.utils.alipay.config.YsAlipayConfig;
import com.ys.utils.alipay.model.MsgInfo;
import com.ys.utils.base.j2se.*;
import com.ys.utils.datasource.DynamicDataSourceContextHolder;
import com.ys.utils.hjzf.HjzfHandler;
import com.ys.utils.mobao.MobaoPay;
import com.ys.utils.mobao.Mobo360Config;
import com.ys.utils.pay.Result;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.UserKey;
import com.ys.utils.spring.properties.Config;
import com.ys.web.ali.manager.YsAlipayConfigManager;
import com.ys.web.mobao.service.MobaoWithholdingService;
import com.ys.web.pay.PayEnum;
import com.ys.web.pay.manager.PayManager;
import com.ys.web.pay.model.WithdrawRecordWait;
import com.ys.web.user.risk.Risk;
import com.ys.web.user.risk.RiskService;
import com.ys.web.yinsheng.model.RequestData;
import com.ys.web.yinsheng.model.UserMerchant;
import com.ys.web.yinsheng.service.YinShengService;
import com.ys.web.yinsheng.util.ServiceEnum;
import com.ys.web.yinsheng.util.YinShengClient;
import lombok.extern.slf4j.Slf4j;
import org.nutz.json.Json;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 提现打款任务
 * 每5秒跑一次，找到提现记录，打款
 */
@Component
@Slf4j
public class WithholdingJob implements Job {
    @Autowired
    private MobaoWithholdingService mobaoWithholdingService;
    @Autowired
    private YinShengService yinShengService;
    @Autowired
    private RiskService riskService;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private YsAlipayConfigManager ysAlipayConfigManager;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        if (Boolean.parseBoolean(Config.pp.get("trading.disable"))) {
            log.info("提现打款任务,交易系统已关闭");
            return;
        }
        log.info("提现打款任务-------开始");
        if(!Logger.isOnline()){
            log.info("提现打款任务---当前环境为研发环境----结束");
            return;
        }
        if(StringHandler.getInt(Config.pp.get("wallet.withholding.task.open"),0)==0) {
            log.info("提现打款任务-------延时到账任务已关闭");
            return ;
        }
        List<WithdrawRecordWait> list = mobaoWithholdingService.getWithdrawRecordListTask(DateHandler.getLongFormatDate());
        if(StringHandler.isEmpty(list)){
            log.info("提现打款任务-------没有任务");
            return ;
        }
        for (WithdrawRecordWait record:list) {
            if(StringHandler.getInt(record.withdrawStatus)!=1){
                continue ;
            }
            int i = mobaoWithholdingService.withholdingSuccess(record.id,"6");
            if(i<=0)
                continue ;
            int dayKey = StringHandler.getInt(DateUtil.getYYMMDD());
            String key = UserKey.withholdingCreateKey(dayKey, record.userId);
            try {
                //处理银盛
                if(record.payChannel==1){
                    YinShengClient yinShengClient = new YinShengClient(ServiceEnum.WALLET_WITHDRAW);
                    //提现申请
                    UserMerchant userMerchant = yinShengService.userMerchant(record.userId + "");
                    // 组装业务参数
                    Map<String, Object> requestMap = new HashMap<>();
                    requestMap.put("requestNo", record.orderNo);
                    requestMap.put("merchantNo", userMerchant.merchantNo);//银盛商户号
                    requestMap.put("amount", StringHandler.fenToYuan(record.withdrawAmount+""));//提现金额，单位：元
                    if (StringHandler.getInt(Config.pp.get("ys.pay.test.open"), 0) == 1) {
                        String testUser = StringHandler.getString(Config.pp.get("ys.pay.test.user"), "");
                        if (StringHandler.isNotEmpty(testUser)) {
                            String testUserList[] = testUser.split(",");
                            for (String str : testUserList) {
                                if (StringHandler.getLong(str) == record.userId)
                                    requestMap.put("amount", "0.01");
                            }
                        }
                    }
                    requestMap.put("linkId", record.linkId);//绑卡标识，提现银行卡对应的绑卡标识
                    requestMap.put("remark", "蜂省优选转账");//银行附言
                    requestMap.put("notifyUrl", Mobo360Config._notifyUrl+"/ys/callBack/withdraw/task/notify");//提现结果异步通知地址，为空则不通知
                    RequestData requestData = new RequestData(requestMap);
                    String callback = yinShengClient.requestStrApi(requestData);
                    Map<String, Object> obj = JsonUtil.jsonToBean(callback, Map.class);
                    String remark = "";
                    boolean isTrue = true;
                    String authSn = "";
                    if (!obj.get("code").equals("SYS000")) {
                        remark = "提现打款任务-银盛提现失败:" + StringHandler.getString(obj.get("msg"));
                        log.error(remark,record.id);
                        isTrue = false;
                    } else {
                        if (StringHandler.isNotEmpty(StringHandler.getString(obj.get("bizResponseJson")))) {
                            Map<String, Object> bizResponseJson = JsonUtil.jsonNullToBean(JsonUtil.toJson(obj.get("bizResponseJson")), Map.class);
                            if (bizResponseJson.get("subCode").equals("COM000")) {
                                authSn = StringHandler.getString(bizResponseJson.get("authSn"));
                            } else if (bizResponseJson.get("subCode").equals("COM004")) {
                                authSn = StringHandler.getString(bizResponseJson.get("authSn"));
                            } else {
                                remark = "提现打款任务-银盛提现失败:" + StringHandler.getString(bizResponseJson.get("subMsg"));
                                log.error(remark,record.id);
                                isTrue = false;
                            }
                        } else {
                            remark = "提现打款任务-银盛提现失败:返回信息为空";
                            log.error(remark,record.id);
                            isTrue = false;
                        }
                    }
                    boolean finalIsTrue = isTrue;
                    String finalRemark = remark;
                    DynamicDataSourceContextHolder.setDataSourceKey("ysIm");
                    transactionTemplate.execute(e -> {
                        if (!finalIsTrue) {
                            riskService.saveRisk(new Risk(record.userId, Convert.objToStr(record)));
                            int ii = mobaoWithholdingService.withholdingStatus(record.id,PayEnum.WithdrawStatus.WITHDRAWAL_FAIL.getCode());
                            if(ii<0){
                                log.error("提现打款任务-修改提现失败状态失败" + JsonUtil.toJson(record),record.id);
                                return 0;
                            }
                            Result<?> result2 = PayManager.accountModify(record.userId, PayEnum.AccountFlowType.WITHDRAWAL_FAIL, record.getAmount(), finalRemark,2);
                            if (!result2.success()) {
                                log.error("提现打款任务-银盛提现还原金额失败" + JsonUtil.toJson(record),result2.getMessage(),record.id);
                            }
                        } else {
                            if (record.fee > 0) {
                                //记录手续费
                                mobaoWithholdingService.insertSxf(record.orderNo, record.userId, record.orderNo, record.amount, record.fee, DateHandler.getLongFormatDate(), 3, finalRemark);
                            }
                        }
                        return 1;
                    });
                    DynamicDataSourceContextHolder.clearDataSourceKey();
                }
                //处理摩宝
                if(record.payChannel==2){
                    String freeKey = UserKey.withholdingFreeKey(dayKey, record.getUserId());
                    com.alibaba.fastjson.JSONObject data = MobaoPay.withdraw(record.ip,key,record);
                    if(data.getString("orderStatus").equals("00") || data.getString("orderStatus").equals("09")){
                        //提现成功扣除冻结金额
                        PayManager.accountModify(record.getUserId(), PayEnum.AccountFlowType.WITHDRAWAL_SUCCESS, record.getAmount(), StringHandler.getString(record.getUserId()),1);
                        String orderOutNo = data.getString("orderOutNo");
                        if(StringHandler.isNotEmpty(orderOutNo)){
                            mobaoWithholdingService.orderOutNoUpdate(record.id,orderOutNo,"",PayEnum.WithdrawStatus.WITHDRAWAL_SUCCESS.getCode(),dayKey);
                        }
                        Redis.key.increment(freeKey);
                        Redis.key.setKeyTimeout(freeKey, 86400L);
                    } else {
                        //提现失败退回余额
                        PayManager.accountModify(record.userId, PayEnum.AccountFlowType.WITHDRAWAL_FAIL, record.getAmount(), data.getString("remark"),1);
                        // 保存提现记录
                        record.setWithdrawStatus(PayEnum.WithdrawStatus.WITHDRAWAL_EXC.getCode());
                        record.setRemark(data.getString("remark"));
                        mobaoWithholdingService.withholdingStatus(record.id,PayEnum.WithdrawStatus.WITHDRAWAL_EXC.getCode());
                        log.error("提现打款任务-"+record.id+"-----提现打款任务失败,请核对并修改正确的信息后再试");
                        continue;
                    }
                }
                if(record.payChannel==4){
                    String freeKey = UserKey.withholdingFreeKey(dayKey, record.getUserId());
                    AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
                    model.setOutBizNo(record.orderNo);
                    model.setRemark(record.getRemark());
                    model.setBusinessParams("{\"payer_show_name_use_alias\":\"true\"}");
                    model.setBizScene("DIRECT_TRANSFER");
                    Participant payeeInfo = new Participant();
                    payeeInfo.setIdentity(record.cardNo);
//                    payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
                    payeeInfo.setIdentityType("ALIPAY_USER_ID");
//                    payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
//                    payeeInfo.setName(record.bankName);
                    model.setPayeeInfo(payeeInfo);
                    model.setTransAmount(StringHandler.fenToYuan(record.withdrawAmount+""));
                    model.setProductCode("TRANS_ACCOUNT_NO_PWD");
                    model.setOrderTitle(record.getRemark());
                    MsgInfo msgInfo = null;
                    List<String> obj = JSONObject.parseArray(Config.pp.get("ys.apipay.appid"),String.class);
                    if(!Boolean.parseBoolean(Config.pp.get("ys.ali.pay.appid.all.open"))){
                        AliPayHandler aliPayHandler = new AliPayHandler(Config.pp);
                        msgInfo = aliPayHandler.trans(StringHandler.isNotEmpty(record.appid)?record.appid:obj.get(0),model);
                    }else{
                        YsAlipayConfig ysAlipayConfig = ysAlipayConfigManager.ysAlipayConfig(StringHandler.isNotEmpty(record.appid)?record.appid:obj.get(0));
                        if(StringHandler.isEmpty(ysAlipayConfig)){
                            log.error("支付宝转账----------ysAlipayConfig--------为空");
                            continue;
                        }
                        if(StringHandler.isEmpty(ysAlipayConfig.appId)){
                            log.error("支付宝转账----------appid--------为空");
                            continue;
                        }
                        AliPayHandler aliPayHandler = new AliPayHandler(ysAlipayConfig);
                        msgInfo = aliPayHandler.trans(ysAlipayConfig.appId,model);
                    }
                    log.info("支付宝转账---------------"+ Json.toJson(msgInfo));
                    if(msgInfo.isSuccess){
                        //提现成功扣除冻结金额
                        PayManager.accountModifyZfb(record.getUserId(), PayEnum.AccountFlowType.WITHDRAWAL_SUCCESS, record.getAmount(), StringHandler.getString(record.getUserId()));
                        String orderOutNo = msgInfo.thirdOrder;
                        String payFundOrderId = msgInfo.payFundOrderId;
                        mobaoWithholdingService.orderOutNoUpdate(record.id,orderOutNo,payFundOrderId,PayEnum.WithdrawStatus.WITHDRAWAL_SUCCESS.getCode(),dayKey);
                        Redis.key.increment(freeKey);
                        Redis.key.setKeyTimeout(freeKey, 86400L);
                    } else {
                        //提现失败退回余额
                        PayManager.accountModifyZfb(record.userId, PayEnum.AccountFlowType.WITHDRAWAL_FAIL, record.getAmount(), msgInfo.errMsg);
                        mobaoWithholdingService.withholdingStatus(record.id,PayEnum.WithdrawStatus.WITHDRAWAL_EXC.getCode(),msgInfo.errMsg);
                        log.error("提现打款任务-"+record.id+"-----提现打款任务失败,请核对并修改正确的信息后再试");
                        continue;
                    }
                }
                //汇聚支付
                if(record.payChannel==5){
                    MsgInfo msgInfo = HjzfHandler.trans(record);
                    if(!msgInfo.isSuccess){
                        ///提现失败退回余额
                        PayManager.accountModifyHjzf(record.userId, PayEnum.AccountFlowType.WITHDRAWAL_FAIL, record.getAmount(), msgInfo.errMsg);
                        // 保存提现记录
                        log.error("提现打款任务-"+record.id+"-----提现打款任务失败,请核对并修改正确的信息后再试");
                        continue;
                    }
                }
                Redis.key.increment(key);
                Redis.key.setKeyTimeout(key, 86400L);
            }catch (Exception e){
                log.error("提现打款任务-"+record.id+"-----"+e.getMessage());
                mobaoWithholdingService.withholdingStatus(record.id,PayEnum.WithdrawStatus.WITHDRAWAL_EXC.getCode());
            }
        }
        log.info("提现打款任务-------结束");
    }


}
